package com.yupi.yupicturebackend.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yupi.yupicturebackend.model.dto.picture.PictureAnalysisResult;
import com.yupi.yupicturebackend.model.dto.picture.PictureColorInfo;
import com.yupi.yupicturebackend.model.dto.picture.PictureSimilarityResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 图片智能分析工具类
 * 
 * <p>提供图片内容识别、色彩分析、相似度检测等智能分析功能</p>
 * 
 * @author yupi
 */
@Slf4j
@Component
public class PictureAnalysisUtils {

    /**
     * 分析图片主要颜色
     *
     * @param imageUrl 图片URL
     * @return 颜色分析结果
     */
    public static PictureColorInfo analyzeColors(String imageUrl) {
        try {
            BufferedImage image = ImageIO.read(new URL(imageUrl));
            return analyzeColors(image);
        } catch (IOException e) {
            log.error("读取图片失败: {}", imageUrl, e);
            return new PictureColorInfo();
        }
    }

    /**
     * 分析图片主要颜色
     *
     * @param image 图片对象
     * @return 颜色分析结果
     */
    public static PictureColorInfo analyzeColors(BufferedImage image) {
        Map<String, Integer> colorCount = new HashMap<>();
        int totalPixels = image.getWidth() * image.getHeight();
        
        // 采样分析，提高性能
        int sampleRate = Math.max(1, totalPixels / 10000);
        
        for (int x = 0; x < image.getWidth(); x += sampleRate) {
            for (int y = 0; y < image.getHeight(); y += sampleRate) {
                Color color = new Color(image.getRGB(x, y));
                String colorHex = String.format("#%02x%02x%02x", 
                    color.getRed(), color.getGreen(), color.getBlue());
                colorCount.merge(colorHex, 1, Integer::sum);
            }
        }
        
        // 获取主要颜色
        List<Map.Entry<String, Integer>> sortedColors = colorCount.entrySet()
            .stream()
            .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
            .limit(10)
            .collect(Collectors.toList());
        
        PictureColorInfo colorInfo = new PictureColorInfo();
        if (!sortedColors.isEmpty()) {
            colorInfo.setDominantColor(sortedColors.get(0).getKey());
            colorInfo.setColorPalette(sortedColors.stream()
                .map(Map.Entry::getKey)
                .collect(Collectors.toList()));
            colorInfo.setColorDistribution(colorCount);
        }
        
        // 分析色调
        colorInfo.setColorTone(analyzeColorTone(sortedColors));
        colorInfo.setBrightness(analyzeBrightness(image));
        colorInfo.setContrast(analyzeContrast(image));
        
        return colorInfo;
    }

    /**
     * 计算图片相似度
     *
     * @param imageUrl1 图片1 URL
     * @param imageUrl2 图片2 URL
     * @return 相似度结果
     */
    public static PictureSimilarityResult calculateSimilarity(String imageUrl1, String imageUrl2) {
        try {
            BufferedImage img1 = ImageIO.read(new URL(imageUrl1));
            BufferedImage img2 = ImageIO.read(new URL(imageUrl2));
            return calculateSimilarity(img1, img2);
        } catch (IOException e) {
            log.error("读取图片失败: {} 或 {}", imageUrl1, imageUrl2, e);
            return new PictureSimilarityResult();
        }
    }

    /**
     * 计算图片相似度
     *
     * @param img1 图片1
     * @param img2 图片2
     * @return 相似度结果
     */
    public static PictureSimilarityResult calculateSimilarity(BufferedImage img1, BufferedImage img2) {
        PictureSimilarityResult result = new PictureSimilarityResult();
        
        // 1. 结构相似度 (基于直方图)
        double histogramSimilarity = calculateHistogramSimilarity(img1, img2);
        
        // 2. 感知哈希相似度
        double phashSimilarity = calculatePHashSimilarity(img1, img2);
        
        // 3. 颜色相似度
        double colorSimilarity = calculateColorSimilarity(img1, img2);
        
        // 综合相似度计算
        double overallSimilarity = (histogramSimilarity * 0.4 + phashSimilarity * 0.4 + colorSimilarity * 0.2);
        
        result.setOverallSimilarity(overallSimilarity);
        result.setHistogramSimilarity(histogramSimilarity);
        result.setPhashSimilarity(phashSimilarity);
        result.setColorSimilarity(colorSimilarity);
        result.setSimilarityLevel(getSimilarityLevel(overallSimilarity));
        
        return result;
    }

    /**
     * 检测图片中的文字内容
     *
     * @param imageUrl 图片URL
     * @return 识别的文字内容
     */
    public static String extractText(String imageUrl) {
        // 这里可以集成OCR服务，如百度OCR、腾讯OCR等
        // 示例使用模拟实现
        try {
            // 模拟OCR调用
            JSONObject requestBody = new JSONObject();
            requestBody.set("image_url", imageUrl);
            
            // 这里应该调用真实的OCR API
            // HttpResponse response = HttpRequest.post("OCR_API_URL")
            //     .header("Authorization", "Bearer YOUR_TOKEN")
            //     .body(requestBody.toString())
            //     .execute();
            
            // 模拟返回结果
            return "模拟OCR识别结果：图片中的文字内容";
            
        } catch (Exception e) {
            log.error("OCR识别失败: {}", imageUrl, e);
            return "";
        }
    }

    /**
     * 检测图片中的物体
     *
     * @param imageUrl 图片URL
     * @return 物体检测结果
     */
    public static List<String> detectObjects(String imageUrl) {
        // 这里可以集成物体检测服务，如百度AI、腾讯AI等
        try {
            // 模拟物体检测调用
            JSONObject requestBody = new JSONObject();
            requestBody.set("image_url", imageUrl);
            
            // 模拟返回结果
            return Arrays.asList("人物", "建筑", "天空", "树木");
            
        } catch (Exception e) {
            log.error("物体检测失败: {}", imageUrl, e);
            return new ArrayList<>();
        }
    }

    /**
     * 生成图片标签
     *
     * @param imageUrl 图片URL
     * @return 自动生成的标签列表
     */
    public static List<String> generateTags(String imageUrl) {
        List<String> tags = new ArrayList<>();
        
        try {
            // 1. 基于颜色生成标签
            PictureColorInfo colorInfo = analyzeColors(imageUrl);
            if (StrUtil.isNotBlank(colorInfo.getColorTone())) {
                tags.add(colorInfo.getColorTone());
            }
            
            // 2. 基于物体检测生成标签
            List<String> objects = detectObjects(imageUrl);
            tags.addAll(objects);
            
            // 3. 基于图片尺寸生成标签
            BufferedImage image = ImageIO.read(new URL(imageUrl));
            if (image.getWidth() > image.getHeight()) {
                tags.add("横版");
            } else if (image.getHeight() > image.getWidth()) {
                tags.add("竖版");
            } else {
                tags.add("方形");
            }
            
            // 4. 基于图片大小生成标签
            if (image.getWidth() >= 1920 || image.getHeight() >= 1080) {
                tags.add("高清");
            }
            
        } catch (Exception e) {
            log.error("生成标签失败: {}", imageUrl, e);
        }
        
        return tags.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 分析图片质量
     *
     * @param imageUrl 图片URL
     * @return 质量分析结果
     */
    public static PictureAnalysisResult analyzeQuality(String imageUrl) {
        PictureAnalysisResult result = new PictureAnalysisResult();
        
        try {
            BufferedImage image = ImageIO.read(new URL(imageUrl));
            
            // 分析清晰度
            double sharpness = calculateSharpness(image);
            result.setSharpness(sharpness);
            
            // 分析噪点
            double noise = calculateNoise(image);
            result.setNoise(noise);
            
            // 分析曝光
            double exposure = calculateExposure(image);
            result.setExposure(exposure);
            
            // 综合质量评分
            double qualityScore = calculateQualityScore(sharpness, noise, exposure);
            result.setQualityScore(qualityScore);
            result.setQualityLevel(getQualityLevel(qualityScore));
            
        } catch (Exception e) {
            log.error("图片质量分析失败: {}", imageUrl, e);
        }
        
        return result;
    }

    // ==================== 私有辅助方法 ====================

    /**
     * 分析色调
     */
    private static String analyzeColorTone(List<Map.Entry<String, Integer>> colors) {
        if (CollUtil.isEmpty(colors)) {
            return "未知";
        }
        
        String dominantColor = colors.get(0).getKey();
        Color color = Color.decode(dominantColor);
        
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float hue = hsb[0];
        
        if (hue < 0.08 || hue > 0.92) return "红色调";
        if (hue < 0.17) return "橙色调";
        if (hue < 0.25) return "黄色调";
        if (hue < 0.42) return "绿色调";
        if (hue < 0.58) return "青色调";
        if (hue < 0.75) return "蓝色调";
        return "紫色调";
    }

    /**
     * 分析亮度
     */
    private static double analyzeBrightness(BufferedImage image) {
        long totalBrightness = 0;
        int pixelCount = 0;
        
        for (int x = 0; x < image.getWidth(); x += 10) {
            for (int y = 0; y < image.getHeight(); y += 10) {
                Color color = new Color(image.getRGB(x, y));
                int brightness = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
                totalBrightness += brightness;
                pixelCount++;
            }
        }
        
        return pixelCount > 0 ? (double) totalBrightness / pixelCount / 255.0 : 0.0;
    }

    /**
     * 分析对比度
     */
    private static double analyzeContrast(BufferedImage image) {
        // 简化的对比度计算
        double brightness = analyzeBrightness(image);
        return Math.abs(0.5 - brightness) * 2;
    }

    /**
     * 计算直方图相似度
     */
    private static double calculateHistogramSimilarity(BufferedImage img1, BufferedImage img2) {
        // 简化实现，实际应该计算RGB直方图
        return 0.8; // 模拟值
    }

    /**
     * 计算感知哈希相似度
     */
    private static double calculatePHashSimilarity(BufferedImage img1, BufferedImage img2) {
        // 简化实现，实际应该计算感知哈希
        return 0.75; // 模拟值
    }

    /**
     * 计算颜色相似度
     */
    private static double calculateColorSimilarity(BufferedImage img1, BufferedImage img2) {
        PictureColorInfo color1 = analyzeColors(img1);
        PictureColorInfo color2 = analyzeColors(img2);
        
        // 简化的颜色相似度计算
        if (color1.getDominantColor() != null && color2.getDominantColor() != null) {
            return color1.getDominantColor().equals(color2.getDominantColor()) ? 0.9 : 0.6;
        }
        return 0.5;
    }

    /**
     * 获取相似度等级
     */
    private static String getSimilarityLevel(double similarity) {
        if (similarity >= 0.9) return "极高";
        if (similarity >= 0.7) return "高";
        if (similarity >= 0.5) return "中等";
        if (similarity >= 0.3) return "低";
        return "极低";
    }

    /**
     * 计算图片清晰度
     */
    private static double calculateSharpness(BufferedImage image) {
        // 简化的清晰度计算，实际应该使用拉普拉斯算子等
        return 0.8; // 模拟值
    }

    /**
     * 计算图片噪点
     */
    private static double calculateNoise(BufferedImage image) {
        // 简化的噪点计算
        return 0.2; // 模拟值
    }

    /**
     * 计算图片曝光
     */
    private static double calculateExposure(BufferedImage image) {
        return analyzeBrightness(image);
    }

    /**
     * 计算综合质量评分
     */
    private static double calculateQualityScore(double sharpness, double noise, double exposure) {
        return (sharpness * 0.5 + (1 - noise) * 0.3 + Math.abs(0.5 - exposure) * 0.2);
    }

    /**
     * 获取质量等级
     */
    private static String getQualityLevel(double score) {
        if (score >= 0.8) return "优秀";
        if (score >= 0.6) return "良好";
        if (score >= 0.4) return "一般";
        return "较差";
    }
}
